
export class Vector2D extends Array {
  // 1, 0是单位向量，长度为1
  constructor (x = 1, y = 0) {
    // 继承数组的所有方法和属性，所以创建了一个数组返回，相当于调用
    super(x, y) // 调用父类的constructor(x, y) this指向创建好的数组
  }
  set x (vx) {
    this[0] = vx
  }
  get x () {
    return this[0]
  }
  set y (vy) {
    this[1] = vy
  }
  get y () {
    return this[1]
  }
  get length () {
    return Math.hypot(this.x, this.y)
  }
  // 计算向量与x轴的偏转角度
  get dir () {
    return Math.atan2(this.y, this.x)
  }
  copy () {
    return new Vector2D(this.x, this.y)
  }
  add (v) {
    this.x += v.x
    this.y += v.y
    return this
  }
  sub (v) {
    this.x -= v.x
    this.y -= v.y
    return this
  }
  rotate (rad) {
    // 向量旋转推导
    // 单位圆的半径为r
    // 初始旋转角为θ:
    // x = rcosθ;
    // y = rsinθ;
    // 设旋转的角度为β: 将x，y带入下面式子
    // x1 = rcos(θ + β) = r(cosθcosβ - sinθsinβ) = rcosθcosβ - rsinθsinβ = xcosβ - ysinβ;
    // y1 = rsin(θ + β) = r(sinθcosβ + cosθsinβ) = rsinθcosβ + rcosθsinβ = ycosβ + xsinβ;
    // 单位向量（1, 0)
    const [x, y] = this
    // x1 = xcosβ - ysinβ
    this.x = x * Math.cos(rad) - y * Math.sin(rad)
    // y1 = ycosβ + xsinβ
    this.y = y * Math.cos(rad) + x * Math.sin(rad)

    return this
  }
  scale (len) {
    this.x *= len
    this.y *= len
    return this
  }
  cross (v) {
    return this.x * v.y - v.x * this.y
  }
  dot (v) {
    return this.x * v.x + v.y * this.y
  }
  normalize () {
    return this.scale(1 / this.length)
  }
}
